package top.syfy.xml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;

/**
 * SAX方式解析XML文件
 */
public class ParseBySax {
    public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException {
        // 获取SaxParserFactory实例
        SAXParserFactory factory = SAXParserFactory.newInstance();
        // 获取SAXParser实例
        SAXParser saxParser = factory.newSAXParser();
        // 创建SAXHandler对象
        SAXHandler handler = new SAXHandler();
        saxParser.parse(new File("example.xml"), handler);
    }
}

/**
 * sax解析是从上到下依次解析, 如example.xml中的class -> student -> student -> ...
 */
class SAXHandler extends DefaultHandler {

    /**
     * 节点属性的索引
     */
    static int attributeIndex = 0;

    /**
     * XML文档遍历开始时的操作
     */
    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        System.out.println("=====sax文档解析开始=====\n\n");
    }

    /**
     * XML文档遍历结束时的操作
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
        System.out.println("\n\n=====sax文档解析结束=====");
    }

    /**
     * 每个节点遍历开始时的操作
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        super.startElement(uri, localName, qName, attributes);
        if ("student".equals(qName)) {
            System.out.println("=====开始遍历student节点=====");
            /*
                遍历获取节点属性名称和属性值
                获取属性名称: getLocalName(int index) ==> 其中index为节点属性名称的索引值(从0开始)
                获取属性值: getValue(String attributeName) ==> 其中attributeName为节点属性名称
             */
            String attributeName;
            while ((attributeName = attributes.getLocalName(attributeIndex++)) != null) {
                System.out.println("属性: " + attributeName + "=" + attributes.getValue(attributeName));
            }
        } else if (!"class".equals(qName)) {
            System.out.print("节点名称: " + qName + "=");
        }
    }

    /**
     * 每个节点遍历结束时的操作
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        super.endElement(uri, localName, qName);
        if ("student".equals(qName)) {
            System.out.println("=====结束遍历student节点=====");
            attributeIndex = 0;
        }
    }

    /**
     * 返回的是节点的值
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        super.characters(ch, start, length);
        String value = new String(ch, start, length).trim();
        if (!"".equals(value)) {
            System.out.println(value);
        }
    }
}